import 'dart:io';
import 'dart:ui';
import 'package:flutter/services.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

import 'connect_type.dart';
import 'esc_command.dart';
import 'flutter_xprinter_method_channel.dart';
import 'flutter_xprinter_platform_interface.dart';
import 'flutter_xprinter_win.dart';

typedef SocketDataHandler = void Function(String response);

typedef CallHandler = void Function(String, dynamic);

class FlutterXprinter {
  FlutterXprinter() {
    if (Platform.isWindows) {
      FlutterXprinterPlatform.instance = FlutterXprinterWin();
    } else {
      FlutterXprinterPlatform.instance = MethodChannelFlutterXprinter();
    }
  }

  Future<String?> getPlatformVersion() {
    return FlutterXprinterPlatform.instance.getPlatformVersion();
  }

  void addMethodCallHandler(CallHandler handler) {
    FlutterXprinterPlatform.instance.addMethodCallHandler(handler);
  }

  void scanBluetoothDevices() {
    FlutterXprinterPlatform.instance.scanBluetoothDevices();
  }

  void stopDiscovery() {
    FlutterXprinterPlatform.instance.stopDiscovery();
  }

  void scanUsbDevices() {
    FlutterXprinterPlatform.instance.scanUsbDevices();
  }

  void connect(ConnectType connType, DeviceType deviceType, String address) {
    FlutterXprinterPlatform.instance.connect(connType, deviceType, address);
  }

  void disconnect(String address) {
    FlutterXprinterPlatform.instance.disconnect(address);
  }

  Future<int> sendPrintTask(List<int> bytes, ConnectType connectType,
      DeviceType deviceType, String address) {
    return FlutterXprinterPlatform.instance
        .sendPrintTask(bytes, connectType, deviceType, address);
  }

  void connectSocket(String token, SocketDataHandler handler) {
    final wsUrl = Uri.parse('wss://oapi.jarvisgo.cn/ws/im/$token');
    var channel = WebSocketChannel.connect(wsUrl);

    channel.stream.listen((response) {
      handler(response);
    });
  }
}

class PrintEvent {
  PrintEvent(this.token, this.commands, {this.device});

  final RootIsolateToken token;

  final List<EscCommand> commands;

  final String? device;
}
